import { ApiObject, fetcherResult, Payload, PlainObject } from 'amis-core/lib/types'
import rsqlUtils from '@/core/utils/rsql/rsqlUtils'
import coreConstants from '@/core/constants/coreConstants'
import { RsqlDataOperator } from '@/core/utils/rsql/types/RsqlDataOperator'
import { RsqlDataOperatorEnum } from '@/core/utils/rsql/types/RsqlOperatorEnum'
import serverApiUtils from '@/core/utils/serverApiUtils'
import { SelectControlSchema } from 'amis/lib/renderers/Form/Select'
import ApiConfigDto from '@/core/framework/config/types/model/ApiConfigDto'
import { HttpStatusCode } from 'axios'
import lodash from 'lodash'
import { Option } from 'amis'

export type ServerSelectUtilsProps = {
	originSelectProps?: Partial<SelectControlSchema>
	// 对象关键字字段名
	valueField?: string
	// 组件关键字字段名
	name: string
	// 组件显示名称
	label: string
	// 显示的字段名
	labelField: string
	// 搜索字段名
	searchField: string
	menuTpl: string | undefined
	// 明细接口配置
	detailApiConfig: ApiConfigDto
	// 搜索接口配置
	searchApiConfig: ApiConfigDto
	sourceMenuTpl: string | undefined
	// source发送表达式
	sourceSendOn?: string
	sourceData?: {
		[propName: string]: any
	}
	options?: Array<Option> | string[] | PlainObject
	autoCompleteMenuTpl: string | undefined
	autoCompleteSendOn?: string
	autoCompleteTrackExpression?: string
	// 自动实例请求适配器
	autoCompleteRequestAdaptorHandler: (
		api: ApiObject,
		context: any,
		rsqlOperator: RsqlDataOperator[],
	) => ApiObject | Promise<ApiObject>
}

class ServerSelectUtils {
	getSchema = (parmas: ServerSelectUtilsProps): SelectControlSchema => {
		const { name, label, detailApiConfig, searchApiConfig, labelField, searchField, autoCompleteRequestAdaptorHandler } = parmas
		const valueField = parmas.valueField ? parmas.valueField : parmas.name
		const sourceSendOn = parmas.sourceSendOn
			? parmas.sourceSendOn
			: `this.${name} && this.${name} !== "" && this.${name} !== undefined && this.${name} !== null`

		const sourceData = parmas.sourceData
			? parmas.sourceData
			: {
					id: `\${${name}}`,
			  }

		const autoCompleteSendOn = parmas.autoCompleteSendOn
			? parmas.autoCompleteSendOn
			: 'this.term !== "" && this.term !== undefined && this.term !== null'

		const mergeSchema = lodash.merge(
			{
				type: 'select',
				name: name,
				label: label,
				options: parmas.options,
				source: {
					url: serverApiUtils.getUriOrMockUri(detailApiConfig),
					method: detailApiConfig.method,
					data: sourceData,
					adaptor: (payload: object, response: fetcherResult, api: ApiObject, context: any): any => {
						console.log(payload)
						if (response.status !== HttpStatusCode.Ok) {
							return payload
						}

						const payloadObjType = payload as Payload
						if (!(payloadObjType && payloadObjType.status === 0)) {
							return payload
						}

						let newLabel = lodash.get(payloadObjType.data, labelField)
						if (parmas.sourceMenuTpl) {
							const compiler = lodash.template(parmas.sourceMenuTpl)
							newLabel = compiler(payloadObjType.data)
						}
						const newData = {
							value: lodash.get(payloadObjType.data, valueField),
							options: [
								{
									label: newLabel,
									value: lodash.get(payloadObjType.data, valueField),
								},
							],
						}
						payloadObjType.data = newData
						return payloadObjType
					},
					sendOn: sourceSendOn,
				} as ApiObject,
				autoComplete: {
					url: serverApiUtils.getUriOrMockUri(searchApiConfig),
					method: searchApiConfig.method,
					// responseData: {
					// 	options: autoCompleteResponseDataOptions,
					// },
					adaptor: (payload: object, response: fetcherResult, api: ApiObject, context: any): any => {
						console.log(payload)
						if (response.status !== HttpStatusCode.Ok) {
							return payload
						}

						const payloadObjType = payload as Payload
						if (!(payloadObjType && payloadObjType.status === 0)) {
							return payload
						}

						const data = payloadObjType.data.items as []
						if (!data || data.length === 0) {
							return payload
						}
						const newData: any[] = lodash.map(data, item => {
							const id = lodash.get(item, valueField) as any
							let newLabel = lodash.get(item, labelField) as any
							if (parmas.autoCompleteMenuTpl) {
								const compiler = lodash.template(parmas.autoCompleteMenuTpl)
								newLabel = compiler(item)
							}
							return {
								label: newLabel,
								value: id,
							}
						})
						payloadObjType.data = {
							options: newData,
						}
						return payloadObjType
					},
					requestAdaptor: (api: ApiObject, context: any): ApiObject | Promise<ApiObject> => {
						const operators: RsqlDataOperator[] = [
							{
								operator: RsqlDataOperatorEnum.LIKE_RIGHT,
								propertyName: `${searchField}`,
							} as RsqlDataOperator,
							{
								operator: RsqlDataOperatorEnum.EQUAL,
								propertyName: coreConstants.deleteFlagFieldName,
							} as RsqlDataOperator,
						]
						const term = context['term']
						if (term) {
							context[`${searchField}`] = term
						}

						context[coreConstants.deleteFlagFieldName] = coreConstants.notDeleteFlag
						autoCompleteRequestAdaptorHandler && autoCompleteRequestAdaptorHandler(api, context, operators)
						api = rsqlUtils.addRsqlFilter(api, context, coreConstants.api.queryFilterName, operators)
						return api
					},
					sendOn: autoCompleteSendOn,
					trackExpression: parmas.autoCompleteTrackExpression,
				} as ApiObject,
			} as SelectControlSchema,
			parmas.originSelectProps,
		)

		const schema = mergeSchema as SelectControlSchema
		return schema
	}
}

export default new ServerSelectUtils()
